import 'package:flutter/material.dart';
import 'dart:math';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: '交错动画'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _time;
  late Animation<double> _offset;
  late Animation<Color?> _color;

  final wheelSize = 80.0;

  @override
  void initState() {
    _controller = AnimationController(duration: Duration(seconds: 4), vsync: this)
                    ..addListener(() {
                      setState(() {});
                    });

    _time = Tween<double>(begin: 0, end: 8.0).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(0.0, 1.0, curve: Curves.linear),
      ),
    );

    _offset = Tween<double>(begin: 0, end: 1.0).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(0.0, 1.0, curve: Curves.easeInCubic),
      ),
    );

    _color = ColorTween(begin: Colors.black87, end: Colors.green).animate(
      CurvedAnimation(
        parent: _controller,
        curve: Interval(0.0, 0.8, curve: Curves.easeIn),
      ),
    );

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    final bottomHeight = MediaQuery.of(context).size.height / 3;
    return Scaffold(
      appBar: AppBar(title: Text(widget.title)),
      body: Stack(
        children: [
          Positioned(
            child: Container(width: double.infinity, height: bottomHeight, color: Colors.green[400]),
            bottom: 0,
            left: 0,
            right: 0
          ),
          Positioned(
            child: Wheel(size: wheelSize, color: _color.value!, time: _time.value),
            bottom: bottomHeight,
            left: _offset.value * MediaQuery.of(context).size.width,
            right: 0
          ),
          Positioned(
            child: Wheel(size: wheelSize, color: _color.value!, time: _time.value),
            bottom: bottomHeight,
            right: _offset.value * MediaQuery.of(context).size.width,
          ),
        ]
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.play_arrow),
        onPressed: () {
          if (_controller.isCompleted) {
            _controller.reverse();
          } else if (!_controller.isAnimating) {
            _controller.forward();
          }
        }
      ),
    );
  }
}

class Wheel extends StatelessWidget {
  const Wheel({Key? key, required this.size, required this.time, required this.color}) : super(key: key);

  final double size;
  final Color color;
  final double time;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: size,
      height: size,
      transform: Matrix4.identity()..rotateZ(2 * pi * time),
      transformAlignment: Alignment.center,
      decoration: BoxDecoration(
        border: Border.all(color: color, width: 10.0),
        borderRadius: BorderRadius.circular(size / 2),
        gradient: LinearGradient(
          colors: [
            Colors.white,
            Colors.orange[100]!,
            Colors.orange[400]!
          ],
        )
      )
    );
  }
}
